/**
 * 
 */
package com.uit.project.bustrip.bo;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.json.JSONObject;

import android.content.ContentValues;
import android.content.Context;

import com.uit.project.bustrip.bointerface.BaseBO;
import com.uit.project.bustrip.daointerface.BaseDao;
import com.uit.project.bustrip.database.DBHelper;
import com.uit.project.bustrip.factory.DaoFactory;
import com.uit.project.bustrip.valueobject.QueryOption;

/**
 * @author Nguyen
 *
 */
public class BaseBOImpl<T, ID> implements BaseBO<T, ID> {
	protected BaseDao<T, ID> dao;
	private Class<T> entityClass;
	private Class<ID> idClass;
	private Context context;
	@SuppressWarnings("unchecked")
	public BaseBOImpl(){
		this.entityClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
		this.idClass = (Class<ID>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[1];
	}
	@SuppressWarnings("unchecked")
	public BaseBOImpl(Context context){
		this.entityClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
		this.idClass = (Class<ID>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[1];
		this.setContext(context);
	}
	
	@Override
	public Class<T> getEntityClass() {
		return (Class<T>) entityClass;
	}

	@Override
	public String getTableName() {
		return this.dao.getTableName();
	}

	@Override
	public List<T> findAll() {
		return this.dao.findAll();
	}

	@Override
	public List<T> find(QueryOption options) {
		return this.dao.find(options);
	}

	@Override
	public T findById(ID id) {
		return this.dao.findById(id);
	}

	@Override
	public ContentValues getContentValues(T entity) {
		return this.dao.getContentValues(entity);
	}

	@Override
	public long insert(T entity) {
		return this.dao.insert(entity);
	}

	@Override
	public int update(T entity) {
		return this.dao.update(entity);
	}

	@Override
	public int updateBy(T entity, String whereClause, String[] whereArgs) {
		return this.dao.updateBy(entity, whereClause, whereArgs);
	}

	@Override
	public int insertOrUpdate(T entity) {
		return this.dao.insertOrUpdate(entity);
	}

	@Override
	public int delete(ID id) {
		return this.dao.delete(id);
	}

	@Override
	public int deleteAll() {
		return this.dao.deleteAll();
	}

	@Override
	public int deleteBy(String whereClause, String[] whereArgs) {
		return this.dao.deleteBy(whereClause, whereArgs);
	}

	/**
	 * @return the dao
	 */
	public BaseDao<T, ID> getDao() {
		return dao;
	}

	/**
	 * @param dao the dao to set
	 */
	public void setDao(BaseDao<T, ID> dao) {
		this.dao = dao;
	}

	/**
	 * @param entityClass the entityClass to set
	 */
	public void setEntityClass(Class<T> entityClass) {
		this.entityClass = entityClass;
	}
	/**
	 * @return the context
	 */
	public Context getContext() {
		return context;
	}
	/**
	 * @param context the context to set
	 */
	@SuppressWarnings("unchecked")
	public void setContext(Context context) {
		this.context = context;
		dao = (BaseDao<T, ID>) DaoFactory.instance(entityClass.getSimpleName());
		DBHelper db = DBHelper.getInstance(context);
		dao.setDbHelper(db);
	}
	/**
	 * @return the idClass
	 */
	public Class<ID> getIdClass() {
		return idClass;
	}
	/**
	 * @param idClass the idClass to set
	 */
	public void setIdClass(Class<ID> idClass) {
		this.idClass = idClass;
	}
	@Override
	public T getFromJSON(JSONObject json) {
		return this.dao.getFromJSON(json);
	}
}
